# backend/api/v1/captcha.py
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel

from backend.core.captcha import create_slider_captcha, generate_token
from backend.utils.cache import set_captcha, get_captcha, delete_captcha, increment_attempt, redis_client

router = APIRouter(prefix="/captcha", tags=["captcha"])


class CaptchaResponse(BaseModel):
    token: str
    background_image: str
    slider_image: str
    slider_width: int = 50
    correct_position: int


class VerifyCaptchaRequest(BaseModel):
    token: str
    user_offset: int
    tolerance: int = 15


@router.get("/slider", response_model=CaptchaResponse)
async def get_slider_captcha():
    """
    获取滑块验证码
    """
    try:
        correct_offset, bg_img_base64, slider_img_base64 = create_slider_captcha()

        token = generate_token()
        # 存储验证码信息，包含状态标记
        set_captcha(token, correct_offset, expire_minutes=5)

        print(f"🎯 生成验证码 - 正确位置: {correct_offset}, Token: {token}")

        return {
            "token": token,
            "background_image": f"data:image/png;base64,{bg_img_base64}",
            "slider_image": f"data:image/png;base64,{slider_img_base64}",
            "slider_width": 50,
            "correct_position": correct_offset
        }

    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail=f"验证码生成失败: {str(e)}"
        )


@router.post("/verify")
async def verify_captcha(request: VerifyCaptchaRequest):
    """
    验证用户提交的滑块偏移量
    """
    MAX_ATTEMPTS = 5
    try:
        # 1. 检查验证码是否存在
        correct_offset = get_captcha(request.token)
        if not correct_offset:
            raise HTTPException(status_code=400, detail="验证码已过期或不存在")

        # 2. 记录尝试次数
        attempts = increment_attempt(request.token)
        if attempts > MAX_ATTEMPTS:
            delete_captcha(request.token)
            if redis_client:
                redis_client.delete(f"captcha:attempt:{request.token}")
            raise HTTPException(status_code=400, detail="尝试次数过多，请重新获取验证码")

        # 3. 计算误差
        difference = abs(correct_offset - request.user_offset)

        print(f"🔍 验证调试信息:")
        print(f"   Token: {request.token}")
        print(f"   正确位置: {correct_offset}px")
        print(f"   用户提交位置: {request.user_offset}px")
        print(f"   容差: {request.tolerance}px")
        print(f"   计算误差: {difference}px")
        print(f"   尝试次数: {attempts}/{MAX_ATTEMPTS}")

        if difference <= request.tolerance:
            # ✅ 验证成功 - 标记为已验证，但不删除
            # 使用新的key存储已验证状态
            if redis_client:
                verified_key = f"captcha:verified:{request.token}"
                redis_client.setex(verified_key, 300, str(correct_offset))  # 5分钟有效期

                # 清理尝试次数记录
                redis_client.delete(f"captcha:attempt:{request.token}")

            print("✅ 验证成功 - 标记为已验证")
            return {
                "success": True,
                "message": "验证成功",
                "debug_info": {
                    "correct_position": correct_offset,
                    "user_position": request.user_offset,
                    "difference": difference
                }
            }
        else:
            # ❌ 验证失败，允许重试
            print("❌ 验证失败")
            return {
                "success": False,
                "message": f"验证失败，请重试 (误差: {difference}px, 尝试 {attempts}/{MAX_ATTEMPTS})",
                "debug_info": {
                    "correct_position": correct_offset,
                    "user_position": request.user_offset,
                    "difference": difference
                }
            }

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"验证过程出错: {str(e)}")